
/**
 * @(#)ConnectFourCore.java
 *
 *
 * @author
 * @version 1.00 2012/3/9
 */

import java.lang.StringBuilder;
import java.util.Arrays;
import java.util.Scanner;
import javax.swing.Timer;

public class ConnectFourCore {

	private int[][] board;
	private int currentPlayer;

	//With this constructor, the game can start at any state
    public ConnectFourCore(int[][] state, int player) {
    	board = state;
    	currentPlayer = player;
    	
    }
    public ConnectFourCore(String data) { Load(data); }

    public void Drop(int col)
    {
    	if(board[0][col]!=0)
    		return;
    	for(int i = board.length-1; i >= 0; i--)
    		if(board[i][col] == 0) { board[i][col] = currentPlayer; break; }
    	if(HasWon()==0)
    		SwitchPlayer();
    
    }

    public void Flip()
    {
    	int colSize=board[0].length;
    	int rowSize=board.length;
    	int[][] copy= new int[rowSize][colSize];
    	for(int column = 0; column< colSize; column++)
    		for(int row= 0; row<rowSize; row++)
    	{
       		copy[(rowSize-1)-row][column]=board[row][column];
    	}
    	board=BubbleUp(copy);
    	SwitchPlayer();
    }
    
    private int[][] BubbleUp(int[][] bubArray)
    {
    	int colSize=bubArray[0].length;
    	int rowSize=bubArray.length;
    	
    	for(int column = 0; column<colSize; column++)
    	{
    		int iterations=0;
    		while(bubArray[rowSize-1][column]==0 && iterations<=rowSize)
    		{
    			//store last element
    			int last=bubArray[rowSize-1][column];
	    		for(int row=rowSize-1; row>0; row--)
	    		{
	    			//shift everything by one
	    			bubArray[row][column]=bubArray[row-1][column];
	    		}
	    		bubArray[0][column]=last;
	    		iterations++;
    		}
		}
    	
    	return bubArray;
  	}
    
    
    int GetCurrentPlayer() {
    	return currentPlayer;
    
    }
    public void Remove(int col)
    {
      	board[board.length-1][col]=0;
    	board=BubbleUp(board);
    	SwitchPlayer();
    }

    int[][] GetCurrentState()
    {
    	return board;
    }

    private void SwitchPlayer()
    {
    	currentPlayer = (currentPlayer%2)+1;
    }


    //Might be better to combine the last two
    int HasWon()
    {
    	 int win = 0;
     	
     	//horizontal and vertical check
     	for (int row=0; row<board[0].length; row++) {
     	  for (int column=0; column<(board.length-3); column++) {
     	    if (board[column][row] != 0 &&
     	        board[column][row] == board[column+1][row] &&
     	        board[column][row] == board[column+2][row] &&
     	        board[column][row] == board[column+3][row]) {
     	      win = 1;
     	    }
     	  }
     	}
     	for (int row=0; row<(board[0].length-3); row++) {
     	  for (int column=0; column<board.length; column++) {
     	    if (board[column][row] != 0 &&
     	        board[column][row] == board[column][row+1] &&
     	        board[column][row] == board[column][row+2] &&
     	        board[column][row] == board[column][row+3]) {
     	      win = 1;
     	    }
     	  }
     	}
     	
     	// diagonals check
     	for (int row=0; row<(board[0].length-3); row++) {
     	  for (int column=0; column<(board.length-3); column++) {
     	    if (board[column][row] != 0 &&
     	        board[column][row] == board[column+1][row+1] &&
     	        board[column][row] == board[column+2][row+2] &&
     	        board[column][row] == board[column+3][row+3]) {
     	      win = 1;
     	    }
     	  }
     	}
     	
     	for (int row=3; row<board[0].length; row++) {
     	  for (int column=0; column<(board.length-3); column++) {
     	    if (board[column][row] != 0 &&
     	        board[column][row] == board[column+1][row-1] &&
     	        board[column][row] == board[column+2][row-2] &&
     	        board[column][row] == board[column+3][row-3]) {
     	      win = 1;
     	    }
     	  }
     	}
     	Boolean isfull=true;
     	for (int row=0; row<board[0].length; row++)
       	  for (int column=0; column<board.length; column++)
       	  {
       		  if(board[column][row]==0)
       			  isfull=false;
       	  }
     	if(isfull)
     		return 3;
     	
     	return win;
    }


    String ToString()
    {
    	StringBuilder sb = new StringBuilder();
    	for(int i = 0; i < board.length; i++) {
    		for(int j = 0; j < board[i].length; j++){
    			sb.append(board[i][j]+",");
    		}
    		sb.replace(sb.length()-1,sb.length()-1,"\n");
    	}
    	sb.append(currentPlayer);

    	return sb.toString();
    }

    private void Load(String data)
    {
    	String[] lines = data.trim().split("\n");
    	int rows = lines.length - 1;
    	int cols = lines[0].split(",").length;

    	board = new int[rows][cols];

    	Scanner scan;

    	for(int i = 0; i < rows; i++)
    	{
    		int j = 0;
    		scan = new Scanner(lines[i]).useDelimiter(",");
    		while(scan.hasNextInt())
    		{
    			board[i][j] = scan.nextInt();
    			j++;
    		}
    		scan.close();
    	}

    	currentPlayer = Integer.parseInt(lines[rows]);
    }
}